package Spam;

import static org.junit.Assert.*;

import java.util.LinkedList;

import org.junit.Test;

import birdsong.comm.ServerComm;
import birdsong.comm.ServerSideMessage;
import birdsong.comm.ServerSideMessage.Type;

public class spamFilterTest {

	@Test
	public void test(){

//LIST OF MESSAGES//
			
		TestServerSideMessage um =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "um", "Ricardo");
		TestServerSideMessage dois =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "dois", "Ricardo");
		TestServerSideMessage tres =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "tres", "Ricardo");
		TestServerSideMessage quatro =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "quatro", "Ricardo");
		TestServerSideMessage seis =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "cinco", "Ricardo");
		TestServerSideMessage sete =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "seis", "Ricardo");
		TestServerSideMessage oito =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "sete", "Ricardo");
		TestServerSideMessage nove =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "oito", "Ricardo");	
		TestServerSideMessage treze =  new TestServerSideMessage(Type.FOLLOW, "teste2", "Carlos");
		TestServerSideMessage teste1 =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "teste1", "ines");
		TestServerSideMessage teste2 =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "teste2", "ines");
		TestServerSideMessage teste3 =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "teste3", "ines");
		TestServerSideMessage teste4 =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "teste4", "ines");
		TestServerSideMessage teste5 =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "teste5", "ines");
		TestServerSideMessage teste6 =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "teste6", "ines");
		TestServerSideMessage teste7 =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "teste7", "ines");
		TestServerSideMessage teste8 =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "teste8", "ines");
		TestServerSideMessage teste9 =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "quatro", "ines");
		TestServerSideMessage teste10 =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "teste10", "ines");
		TestServerSideMessage teste11 =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "teste11", "ines");
		TestServerSideMessage teste12 =  new TestServerSideMessage(Type.BIRDSONG_MESSAGE, "teste12", "ines");
		

//OFFER THE MESSAGES TO THE LINKED LIST

		LinkedList<ServerSideMessage> listOfMessages = new LinkedList<ServerSideMessage>();
			
/*1*/	listOfMessages.offer(um);
/*2*/	listOfMessages.offer(dois);
/*3*/	listOfMessages.offer(tres);
/*4*/	listOfMessages.offer(quatro);
/*5*/	listOfMessages.offer(quatro);
/*6*/	listOfMessages.offer(seis);
/*7*/	listOfMessages.offer(sete);
/*8*/	listOfMessages.offer(oito);
/*9*/	listOfMessages.offer(nove);
/*10*/	listOfMessages.offer(quatro);
/*11*/	listOfMessages.offer(quatro);
/*12*/	listOfMessages.offer(treze);
/*13*/	listOfMessages.offer(teste1);
/*14*/	listOfMessages.offer(teste2);
/*15*/	listOfMessages.offer(teste3);
/*16*/	listOfMessages.offer(teste4);
/*17*/	listOfMessages.offer(teste5);
/*18*/	listOfMessages.offer(teste6);
/*19*/	listOfMessages.offer(teste7);
/*20*/	listOfMessages.offer(teste8);
/*21*/	listOfMessages.offer(teste9);
/*22*/	listOfMessages.offer(teste10);
/*23*/	listOfMessages.offer(teste11);
/*24*/	listOfMessages.offer(teste12);
/*25*/	listOfMessages.offer(teste12);
/*26*/	listOfMessages.offer(um);
/*27*/	listOfMessages.offer(tres);

//OFFER THE DELAY FOR EACH MESSAGE TO BE SENT

		LinkedList<Integer> delay = new LinkedList<Integer>();
		
/*1*/	delay.offer(10000);
/*2*/	delay.offer(5000);
/*3*/	delay.offer(2000);
/*4*/	delay.offer(1000);
/*5*/	delay.offer(0);
/*6*/	delay.offer(0);
/*7*/	delay.offer(0);
/*8*/	delay.offer(0);
/*9*/	delay.offer(0);
/*10*/	delay.offer(0);
/*11*/	delay.offer(0);
/*12*/	delay.offer(0);
/*13*/	delay.offer(0);
/*14*/	delay.offer(0);
/*15*/	delay.offer(0);
/*16*/	delay.offer(0);
/*17*/	delay.offer(0);
/*18*/	delay.offer(0);
/*19*/	delay.offer(0);
/*20*/	delay.offer(0);
/*21*/	delay.offer(0);
/*22*/	delay.offer(5000);
/*23*/	delay.offer(5000);
/*24*/	delay.offer(5000);
/*25*/	delay.offer(15000);
/*26*/	delay.offer(0);
/*27*/	delay.offer(30000);
		
// ASSERT RESULTS

		TestServerComm TestServerComm = new TestServerComm(listOfMessages, delay);
		spamFilter spamFilter = new spamFilter(TestServerComm);
		
/*1*/	assertEquals("Message not blocked",	um ,spamFilter.getNextMessage());
/*2*/	assertEquals("Message not blocked",	dois, spamFilter.getNextMessage());
/*3*/	assertEquals("Message not blocked",	tres, spamFilter.getNextMessage());
/*4*/	assertEquals("Message not blocked",	quatro, spamFilter.getNextMessage());
		assertEquals("Number of Messages on List", 1, spamFilter.numberOfMessages(quatro.getPayload(), quatro.getClientNickname()));
/*5*/	assertEquals("Message not blocked",	quatro, spamFilter.getNextMessage());
		assertEquals("Number of Messages on List", 2, spamFilter.numberOfMessages(quatro.getPayload(), quatro.getClientNickname()));

/*6*/	assertEquals("Message not blocked", seis, spamFilter.getNextMessage());
/*7*/	assertEquals("Message not blocked",	sete, spamFilter.getNextMessage());
/*8*/	assertEquals("Message not blocked",	oito, spamFilter.getNextMessage());
/*9*/	assertEquals("Message not blocked",	nove, spamFilter.getNextMessage());
/*10*/	assertEquals("Message not blocked",	quatro, spamFilter.getNextMessage());
		assertEquals("Number of Messages on List", 3, spamFilter.numberOfMessages(quatro.getPayload(),quatro.getClientNickname()));
		
		assertFalse("Ricardo not Blocked", spamFilter.clientBlocked("Ricardo"));
/*11*/	ServerSideMessage message = spamFilter.getNextMessage();
		assertEquals("Number of repeated messages reached limit", 3, spamFilter.numberOfMessages(quatro.getPayload(),quatro.getClientNickname()));
		assertEquals("Ricardo Disconnected", Type.CLIENT_DISCONNECTED, message.getType());
		assertTrue("Ricardo Blocked", spamFilter.clientBlocked("Ricardo"));
		
		

/*12*/	message = spamFilter.getNextMessage();
		assertEquals("Message to Follow User", Type.FOLLOW, message.getType());

/*13*/	assertEquals("Message not blocked",	teste1 ,spamFilter.getNextMessage());
/*14*/	assertEquals("Message not blocked",	teste2 ,spamFilter.getNextMessage());
/*15*/	assertEquals("Message not blocked",	teste3 ,spamFilter.getNextMessage());
/*16*/	assertEquals("Message not blocked",	teste4 ,spamFilter.getNextMessage());
/*17*/	assertEquals("Message not blocked",	teste5 ,spamFilter.getNextMessage());
/*18*/	assertEquals("Message not blocked",	teste6 ,spamFilter.getNextMessage());
/*19*/	assertEquals("Message not blocked",	teste7 ,spamFilter.getNextMessage());
/*20*/	assertEquals("Message not blocked",	teste8 ,spamFilter.getNextMessage());

		assertFalse("Ines not Blocked", spamFilter.clientBlocked("ines"));
/*21*/	message = spamFilter.getNextMessage();
		assertEquals("Message not blocked",	teste9 ,message);
		assertEquals("Number of Messages on List", 1, spamFilter.numberOfMessages(teste9.getPayload(), teste9.getClientNickname()));
		assertFalse("Ines not Blocked", spamFilter.clientBlocked("ines"));

/*22*/	assertEquals("Message not blocked",	teste10 ,spamFilter.getNextMessage());

		assertFalse("Ines not Blocked", spamFilter.clientBlocked("ines"));
		assertTrue("Ricardo Blocked", spamFilter.clientBlocked("Ricardo"));
/*23*/	message = spamFilter.getNextMessage();		
		assertEquals("Number of overall messages reached limit", 10, spamFilter.numberUserAccess(teste11.getClientNickname()));
		assertEquals("Client Disconnected", Type.CLIENT_DISCONNECTED, message.getType());
		assertTrue("Ines Blocked", spamFilter.clientBlocked("ines"));
		assertTrue("Ricardo Blocked", spamFilter.clientBlocked("Ricardo"));


/*24*/	message = spamFilter.getNextMessage();
		assertEquals("Number of overall messages reached limit", 10, spamFilter.numberUserAccess(teste12.getClientNickname()));
		assertTrue("Ines Blocked", spamFilter.clientBlocked("ines"));
		assertTrue("Ricardo Blocked", spamFilter.clientBlocked("Ricardo"));

/*25*/	message = spamFilter.getNextMessage();
		assertTrue("Ines Blocked", spamFilter.clientBlocked("ines"));
		assertFalse("Ricardo Not Blocked", spamFilter.clientBlocked("Ricardo"));
		assertEquals("Ines Disconnected", Type.CLIENT_DISCONNECTED, message.getType());

/*26*/ 	assertEquals("Message not blocked",	um, spamFilter.getNextMessage());

/*27*/	message = spamFilter.getNextMessage();
		assertFalse("Ines Not Blocked", spamFilter.clientBlocked("ines"));
		assertFalse("Ricardo Not Blocked", spamFilter.clientBlocked("Ricardo"));
		assertEquals("Message not blocked",	tres, message);
		
/*28*/ 	spamFilter.getNextMessage();
	
	}

}
